rm(list = ls()) # clean-up workspace
library("tidyverse")
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──
## ✓ ggplot2 3.3.5     ✓ purrr   0.3.4
## ✓ tibble  3.1.5     ✓ dplyr   1.0.7
## ✓ tidyr   1.1.4     ✓ stringr 1.4.0
## ✓ readr   2.0.1     ✓ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()

Some more exercise on ggplot2

embed a plot inside another

In this part, we want to replicate the plots in reference.

  1. create the data and do the initial visualization
set.seed(42)
n <- 1000
x <- runif(n) * 3
y <- x * sin(1/x) + rnorm(n) / 25
df <- tibble(x = x, y = y)
p1 <- ggplot(df, aes(x, y)) +
  geom_point(alpha = 0.3) +
  geom_smooth(se = FALSE) +
  theme_bw()
p1
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'

Let’s further take a look over the function \(f(x) = x \sin(\frac{1}{x})\).

Create a new variable \(z\) to store the \(f(x)\) values at each \(x\) point.

df.with.z <- df %>%
  add_column(z = x * sin(1 / x))

Now plot another figure with two layers:

  • Scatter plot of the points (x, y)

  • A line by (x, z)

Put your code inside the code block, explain your findings outside the code block (so that it renders to text in the HTML file).

You may want to change eval = TRUE or remove it for the code to be executed.

p2 <- ggplot(df.with.z, mapping = aes(x = x, y = y)) + 
  geom_point(alpha = 0.3) +
  geom_line(mapping = aes(x = x, y = z), color = "red", linetype = "dotted") +
  theme_bw()
p2

Now we see that the default smoothing function doesn’t catch the beginning part of these points.

Let’s zoom in (with clipping) the region \(x \in [0, 0.5]\) and make another plot.

p3 <- ggplot(df, aes(x, y)) +
    geom_point(alpha = 0.3) +
    geom_smooth(se = FALSE) +
    scale_x_continuous(limits = c(0, 0.5)) +
    scale_y_continuous(limits = c(-0.3, 0.6)) +
    theme_bw()
p3
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
## Warning: Removed 812 rows containing non-finite values (stat_smooth).
## Warning: Removed 812 rows containing missing values (geom_point).

Now embed p3 inside p1.

Please add appropriate titles and subtitles to them.

p1 + annotation_custom(ggplotGrob(p3), xmin = 1, xmax = 3, ymin = -0.3, ymax = 0.6)
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
## Warning: Removed 812 rows containing non-finite values (stat_smooth).
## Warning: Removed 812 rows containing missing values (geom_point).
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'


Now please follow the second half of the reference, but instead create a UK map similar to this one and save it as uk_map.pdf

Hint: it’s time to practice your self-learning (google?) skills.


Target UK map


A bad map your instructor created.

# Your code for the UK map
library(ggmap)
## Google's Terms of Service: https://cloud.google.com/maps-platform/terms/.
## Please cite ggmap if you use it! See citation("ggmap") for details.
uk_bbox <- c(left = -12, bottom = 49.8, right = 2, top = 60.15456)
uk_main_map <- get_stamenmap(uk_bbox, zoom = 6, maptype = "terrain")
## Source : http://tile.stamen.com/terrain/6/29/18.png
## Source : http://tile.stamen.com/terrain/6/30/18.png
## Source : http://tile.stamen.com/terrain/6/31/18.png
## Source : http://tile.stamen.com/terrain/6/32/18.png
## Source : http://tile.stamen.com/terrain/6/29/19.png
## Source : http://tile.stamen.com/terrain/6/30/19.png
## Source : http://tile.stamen.com/terrain/6/31/19.png
## Source : http://tile.stamen.com/terrain/6/32/19.png
## Source : http://tile.stamen.com/terrain/6/29/20.png
## Source : http://tile.stamen.com/terrain/6/30/20.png
## Source : http://tile.stamen.com/terrain/6/31/20.png
## Source : http://tile.stamen.com/terrain/6/32/20.png
## Source : http://tile.stamen.com/terrain/6/29/21.png
## Source : http://tile.stamen.com/terrain/6/30/21.png
## Source : http://tile.stamen.com/terrain/6/31/21.png
## Source : http://tile.stamen.com/terrain/6/32/21.png
p_main <- ggmap(uk_main_map) +
  xlab("longitude") +
  ylab("Latitude") +
  scale_x_continuous(breaks = c(-8, -4, 0), labels = c("8°W", "4°W", "0"))
## Scale for 'x' is already present. Adding another scale for 'x', which will
## replace the existing scale.
  theme(axis.text = element_text(size = 16),
        axis.title = element_text(size = 24, face = "bold"))
## List of 2
##  $ axis.title:List of 11
##   ..$ family       : NULL
##   ..$ face         : chr "bold"
##   ..$ colour       : NULL
##   ..$ size         : num 24
##   ..$ hjust        : NULL
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : NULL
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi FALSE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.text :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : num 16
##   ..$ hjust        : NULL
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : NULL
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi FALSE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  - attr(*, "class")= chr [1:2] "theme" "gg"
##  - attr(*, "complete")= logi FALSE
##  - attr(*, "validate")= logi TRUE
p_main

shetland_bbox <- c(left = -2.3, bottom = 59.5, right = -0.5, top = 61.2)
shetland_map <- get_stamenmap(shetland_bbox, zoom = 7, maptype = "terrain") 
## Source : http://tile.stamen.com/terrain/7/63/36.png
## Source : http://tile.stamen.com/terrain/7/63/37.png
p_shetland<- ggmap(shetland_map) + 
    # labs(title = "Shetland Islands") +
    theme(axis.title = element_blank(), 
          axis.text  = element_blank(),
          axis.ticks = element_blank())
p_shetland

library(grid)

p_main +
  inset(ggplotGrob(p_shetland), xmin = -7.8, xmax = -11.8, ymax = 60.1, ymin = 56.0)

ggsave("a_bad_UK_map_example.png", height = 10, width = 8, dpi = "retina")